/*!
 * \file WtExecMgr.cpp
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 执行管理器实现文件
 * 
 * 本文件实现了执行管理器的核心功能，主要包括：
 * 1. 多执行器的统一管理和调度
 * 2. 持仓目标的分发和过滤处理
 * 3. 过滤器的集成应用
 * 4. 行情数据的转发处理
 * 5. 持仓变化事件的处理和分发
 * 
 * 该实现确保了策略信号能够高效、准确地分发给各个执行器，
 * 同时通过过滤器机制提供了灵活的风险控制能力。
 */
#include "WtExecMgr.h"
#include "WtFilterMgr.h"

#include "../Share/decimal.h"

#include "../WTSTools/WTSLogger.h"

USING_NS_WTP;

//////////////////////////////////////////////////////////////////////////
#pragma region "WtExecuterMgr"

/**
 * @brief 枚举所有执行器
 * @param cb 枚举回调函数
 * 
 * 遍历所有已注册的执行器，对每个执行器调用回调函数，
 * 用于批量操作或状态查询
 */
void WtExecuterMgr::enum_executer(EnumExecuterCb cb)
{
	for (auto it = _executers.begin(); it != _executers.end(); it++)
	{
		ExecCmdPtr& executer = (*it);
		cb(executer);
	}
}

/**
 * @brief 设置目标持仓
 * @param target_pos 目标持仓映射表(合约代码->持仓数量)
 * 
 * 将策略的目标持仓分发给所有执行器：
 * 1. 如果配置了过滤管理器，先进行过滤处理
 * 2. 对每个合约代码进行过滤检查
 * 3. 将过滤后的持仓目标分发给所有执行器
 * 4. 对被过滤的执行器跳过信号分发
 */
void WtExecuterMgr::set_positions(faster_hashmap<LongKey, double> target_pos)
{
	if(_filter_mgr != NULL)
	{
		faster_hashmap<LongKey, double> des_port;
		for(auto& m : target_pos)
		{
			const auto& stdCode = m.first;
			double& desVol = (double&)m.second;
			double oldVol = desVol;

			bool isFltd = _filter_mgr->is_filtered_by_code(stdCode.c_str(), desVol);
			if (!isFltd)
			{
				if (!decimal::eq(desVol, oldVol))
				{
					//输出日志
					WTSLogger::info_f("[Filters] {} target position reset by code filter: {} -> {}", stdCode.c_str(), oldVol, desVol);
				}

				des_port[stdCode] = desVol;
			}
			else
			{
				//输出日志
				WTSLogger::info_f("[Filters] {} target position ignored by filter", stdCode.c_str());
			}
		}

		des_port.swap(target_pos);
	}

	for (auto it = _executers.begin(); it != _executers.end(); it++)
	{
		ExecCmdPtr& executer = (*it);
		if (_filter_mgr && _filter_mgr->is_filtered_by_executer(executer->name()))
		{
			WTSLogger::info_f("[Filters] Executer {} is filtered, all signals will be ignored", executer->name());
			continue;
		}
		executer->set_position(target_pos);
	}
}

/**
 * @brief 处理持仓变化
 * @param stdCode 标准合约代码
 * @param targetPos 目标持仓数量
 * 
 * 处理单个合约的持仓变化：
 * 1. 如果配置了过滤管理器，先进行过滤检查
 * 2. 对目标持仓进行过滤处理，可能会调整数量
 * 3. 将持仓变化通知给所有未被过滤的执行器
 */
void WtExecuterMgr::handle_pos_change(const char* stdCode, double targetPos)
{
	if(_filter_mgr != NULL)
	{
		double oldVol = targetPos;
		bool isFltd = _filter_mgr->is_filtered_by_code(stdCode, targetPos);
		if (!isFltd)
		{
			if (!decimal::eq(targetPos, oldVol))
			{
				//输出日志
				WTSLogger::info_f("[Filters] {} target position reset by filter: {} -> {}", stdCode, oldVol, targetPos);
			}
		}
		else
		{
			//输出日志
			WTSLogger::info_f("[Filters] {} target position ignored by filter", stdCode);
			return;
		}
	}
	
	for (auto it = _executers.begin(); it != _executers.end(); it++)
	{
		ExecCmdPtr& executer = (*it);
		if(_filter_mgr && _filter_mgr->is_filtered_by_executer(executer->name()))
		{
			WTSLogger::info_f("[Filters] All signals to executer {} are ignored by executer filter", executer->name());
			continue;
		}
		executer->on_position_changed(stdCode, targetPos);
	}
}

/**
 * @brief 处理行情数据
 * @param stdCode 标准合约代码
 * @param curTick 当前tick数据
 * 
 * 将实时行情数据转发给所有执行器进行处理，
 * 行情数据不进行过滤，直接转发给所有执行器
 */
void WtExecuterMgr::handle_tick(const char* stdCode, WTSTickData* curTick)
{
	for (auto it = _executers.begin(); it != _executers.end(); it++)
	{
		ExecCmdPtr& executer = (*it);
		executer->on_tick(stdCode, curTick);
	}
}
#pragma endregion "WtExecuterMgr"
